# -*- coding: utf-8 -*-
"""
本地存储适配器
用于开发和测试环境的文件存储
"""

import os
import shutil
from typing import BinaryIO, Optional
from flask import current_app

from .base import CloudStorageAdapter


class LocalStorageAdapter(CloudStorageAdapter):
    """本地存储适配器"""
    
    def __init__(self, **config):
        """初始化本地存储适配器
        
        Args:
            **config: 配置参数，包含storage_path等参数
        """
        super().__init__(**config)
        self.storage_path = config.get('storage_path', 'uploads')
        
        # 确保存储目录存在
        if not os.path.exists(self.storage_path):
            os.makedirs(self.storage_path, exist_ok=True)
    
    def upload_file(self, file_stream: BinaryIO, file_name: str, 
                   file_size: int, content_type: str = None, file_md5: str = None) -> dict:
        """上传文件到本地存储
        
        Args:
            file_stream: 文件流
            file_name: 文件名
            file_size: 文件大小
            content_type: 文件MIME类型
            file_md5: 文件MD5值（用于分目录存储）
            
        Returns:
            dict: 上传结果
        """
        try:
            # 如果没有提供MD5，则计算MD5
            if not file_md5:
                import hashlib
                file_stream.seek(0)
                md5_hash = hashlib.md5()
                while chunk := file_stream.read(8192):
                    md5_hash.update(chunk)
                file_md5 = md5_hash.hexdigest()
                file_stream.seek(0)
            
            # 按MD5分目录存储：取MD5前2位作为一级目录，3-4位作为二级目录
            # 例如：MD5为abcd1234... -> 存储路径为 uploads/ab/cd/abcd1234..._filename
            dir_level1 = file_md5[:2]
            dir_level2 = file_md5[2:4]
            storage_dir = os.path.join(self.storage_path, dir_level1, dir_level2)
            
            # 确保存储目录存在
            if not os.path.exists(storage_dir):
                os.makedirs(storage_dir, exist_ok=True)
            
            # 构建文件存储路径：使用MD5作为文件名，保留原始扩展名
            file_ext = os.path.splitext(file_name)[1]
            storage_filename = f"{file_md5}{file_ext}"
            local_file_path = os.path.join(storage_dir, storage_filename)
            
            # 如果文件已存在（相同MD5），直接返回成功（去重）
            if os.path.exists(local_file_path):
                file_stat = os.stat(local_file_path)
                from datetime import datetime, timedelta
                return {
                    'success': True,
                    'cloud_file_id': f"{dir_level1}/{dir_level2}/{storage_filename}",
                    'download_url': f'/api/netdisk/download/{dir_level1}/{dir_level2}/{storage_filename}',
                    'expires_at': datetime.utcnow() + timedelta(hours=24),
                    'file_size': file_stat.st_size,
                    'storage_path': local_file_path,
                    'is_duplicate': True
                }
            
            # 保存文件
            with open(local_file_path, 'wb') as f:
                shutil.copyfileobj(file_stream, f)
            
            # 获取文件信息
            file_stat = os.stat(local_file_path)
            
            from datetime import datetime, timedelta
            
            return {
                'success': True,
                'cloud_file_id': f"{dir_level1}/{dir_level2}/{storage_filename}",
                'download_url': f'/api/netdisk/download/{dir_level1}/{dir_level2}/{storage_filename}',
                'expires_at': datetime.utcnow() + timedelta(hours=24),
                'file_size': file_stat.st_size,
                'storage_path': local_file_path,
                'is_duplicate': False
            }
            
        except Exception as e:
            return {
                'success': False,
                'error_message': str(e)
            }
    
    def get_download_url(self, cloud_file_id: str, expires_in: int = 3600) -> dict:
        """获取文件下载链接
        
        Args:
            cloud_file_id: 云端文件ID
            expires_in: 链接有效期（秒）
            
        Returns:
            dict: 下载链接信息
        """
        try:
            local_file_path = os.path.join(self.storage_path, cloud_file_id)
            
            if not os.path.exists(local_file_path):
                return {
                    'success': False,
                    'error_message': 'File not found'
                }
            
            from datetime import datetime, timedelta
            
            return {
                'success': True,
                'download_url': f'/api/netdisk/download/{cloud_file_id}',
                'expires_at': datetime.utcnow() + timedelta(seconds=expires_in)
            }
            
        except Exception as e:
            return {
                'success': False,
                'error_message': str(e)
            }
    
    def delete_file(self, cloud_file_id: str) -> dict:
        """从本地存储删除文件
        
        Args:
            cloud_file_id: 云端文件ID
            
        Returns:
            dict: 删除结果
        """
        try:
            local_file_path = os.path.join(self.storage_path, cloud_file_id)
            
            if os.path.exists(local_file_path):
                os.remove(local_file_path)
            
            return {
                'success': True
            }
            
        except Exception as e:
            return {
                'success': False,
                'error_message': str(e)
            }
    
    def get_file_info(self, cloud_file_id: str) -> dict:
        """获取本地文件信息
        
        Args:
            cloud_file_id: 云端文件ID
            
        Returns:
            dict: 文件信息
        """
        try:
            local_file_path = os.path.join(self.storage_path, cloud_file_id)
            
            if not os.path.exists(local_file_path):
                return {
                    'success': False,
                    'error_message': 'File not found'
                }
            
            file_stat = os.stat(local_file_path)
            
            from datetime import datetime
            
            return {
                'success': True,
                'file_id': cloud_file_id,
                'file_name': os.path.basename(cloud_file_id),
                'file_size': file_stat.st_size,
                'created_at': datetime.fromtimestamp(file_stat.st_ctime),
                'modified_at': datetime.fromtimestamp(file_stat.st_mtime)
            }
            
        except Exception as e:
            return {
                'success': False,
                'error_message': str(e)
            }